import { Component, EventEmitter, forwardRef, Input, OnInit, Output } from '@angular/core';
import { UploadFile, UploadXHRArgs } from '@shared/apes/upload';
import { toBoolean, toNumber } from '@shared/apes/core/util/convert';
import { ApiService } from '@core/services/http/api.service';
import { ApesMessageService } from '@shared/apes/message';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { replaceAll } from '../../../utils/utils';
import { ApesPreviewDialogComponent } from '@shared/ag-grid-ext/upload-component/apes-previewDialog.component';
import { ApesModalService } from '@shared/apes/modal';

@Component({
  selector: 'apes-upload-images',
  templateUrl: './apes-upload-images.component.html',
  // styleUrls: ['./apes-upload-images.component.scss'],
  providers: [
    {
      provide: NG_VALUE_ACCESSOR,
      useExisting: forwardRef(() => ApesUploadImagesComponent),
      multi: true,
    },
  ],
})
export class ApesUploadImagesComponent implements OnInit {
  uploading = false;
  _fileList: UploadFile[] = [];
  previewImage = 'fileserver/view/5ebb8a7f99a45a428ceeb50c';
  previewVisible = false;
  showList: any = {
    showPreviewIcon: true,
    showRemoveIcon: false,
    showDownloadIcon: false,
  };
  @Input() disabled: boolean = false;
  @Input() type: any;
  @Input() title: any = '上传图片';
  @Input() limit: any = 1;
  @Input() showLimitTooltip: boolean = true;
  @Input() showDownload: any;
  @Input() showRemove: any;
  @Input() showButton: boolean = true;
  onChange: (value: any) => void = () => null;
  onTouched: () => void = () => null;

  @Input() customStyle: any;

  _initData: any;

  @Input()
  set initData(value: any) {
    if (typeof value == 'string') {
      value = replaceAll(value, '\"', '"');
      this._initData = value;
      this.fileList = JSON.parse(value) || [];
    }
    // else {
    //   this.fileList = [];
    // }
  }

  get initData() {
    return this._initData;
  }

  @Output('change') changeEvent = new EventEmitter();

  constructor(
    private  apiService: ApiService,
    private msg: ApesMessageService,
    private modalService: ApesModalService,
  ) {
  }

  ngOnInit() {
  }

  get fileList(): UploadFile[] {
    return this._fileList || [];
  }

  set fileList(input: UploadFile[]) {
    let value = input;
    if (this._fileList === value) {
      return;
    }
    this._fileList = value;
  }

  /** 显示数量 **/
  showLimit() {
    if (this.showLimitTooltip) {
      return this.limit ? '允许上传最多' + this.limit + '个文件' : '不限个数';
    } else {
      return null;
    }
  }

  /** 显示上传按钮 **/
  showUploadButton() {
    if (this.disabled) {
      return false;
    } else if (!this.showButton) {
      return false;
    } else {
      return this.fileList.length < this.limit;
    }
  }

  /** 控制上传类型、数量和是否重复**/
  beforeUpload = (file: UploadFile): boolean => {
    let _type = this.type ? this.type : file.type;
    let _limit = toNumber(this.limit, null);
    let tempFileList = this.fileList;
    let isRepeat = false;
    if (_type.indexOf(file.type) == -1 || (file.type == '' && _type != file.type)) {
      this.msg.error('请上传指定类型文件');
      return false;
    }
    // file.thumbUrl = 'fileserver/view/' + file.id;
    if (_limit !== null) {
      if (this.fileList.length < _limit) {
        if (this.fileList.length == 0) {
          // this.fileList.push(file);
        } else {
          tempFileList.map((files) => {
            if (files.name == file.name) {
              isRepeat = true;
            }
          });
          if (isRepeat) {
            this.msg.error('请勿重复上传相同文件');
            return false;
          } else {
            // this.fileList.push(file);
          }
        }
      } else {
        this.msg.error('超出上传限制数量');
        return false;
      }
    } else {
      // this.fileList.push(file);
    }
    return true;
  };

  /** 上传操作 **/
  handleUpload(): void {
    // 判断
    this.uploading = true;
    this.apiService.upload(this.fileList).subscribe(
      (event: any) => {
        const returnFile = event.body;
        // this.formControl.patchValue(returnFile);
        // this.model[this.key] = returnFile;
        this.showFilesList(returnFile);

        this.msg.success('上传成功');
        this.uploading = false;
      },
      err => {
        console.log(err);
        this.uploading = false;
        this.msg.error('上传失败,请核实文件是否能正常上传！');
      },
    );
  }

  customReq = (item: UploadXHRArgs) => {
    const formData = new FormData();
    formData.append('file', item.file as any);
    formData.append('id', '1000');
    return this.apiService.upload([item.file]).subscribe(
      (event: any) => {
        const returnFile = event.body[0];
        this.showFilesList(returnFile);
        this.msg.success('上传成功');
        this.uploading = false;
        item.onSuccess!(event.body, item.file!, event);
      },
      err => {
        console.log(err);
        this.uploading = false;
        this.msg.error('上传失败,请核实文件是否能正常上传！');
      },
    );
  };

  /** 处理上传文件 **/
  showFilesList(returnFile) {
    let bAdd = true;
    for (let item of this.fileList) {
      if (item.name == returnFile.fileName || item.id == returnFile.id) {
        item.thumbUrl = 'fileserver/view/' + returnFile.id;
        item.id = returnFile.id;
        item.status = 'done';
        item.iconType = 'thumbnail';
        item.isUploading = false;
        this.fileList = [...this.fileList];
        bAdd = false;
      }
    }
    if (bAdd) {
      returnFile.thumbUrl = 'fileserver/view/' + returnFile.id;
      returnFile.status = 'done';
      returnFile.iconType = 'thumbnail';
      returnFile.isUploading = false;
      this.fileList = [...this.fileList, returnFile];
    }

    this.onChange(JSON.stringify(this.fileList));
    this.changeEvent.emit(JSON.stringify(this.fileList));
  }

  /** 删除文件 **/
  handleRemove = (file: UploadFile) => {
    if (!this.disabled) {
      this.fileList = this.fileList.filter(x => x.name !== file.name);
      this.onChange(JSON.stringify(this.fileList));
      this.changeEvent.emit(JSON.stringify(this.fileList));
      return true;
    } else {
      return false;
    }

  };

  /** 是否允许下载 **/
  handleShowList = () => {
    // let showDownload = this.showDownload || false;
    let showRemove = this.showRemove || false;
    if (this.disabled) {
      this.showList = {
        showPreviewIcon: true,
        showRemoveIcon: false,
        showDownloadIcon: false,
      };
    } else {
      this.showList = {
        showPreviewIcon: true,
        showRemoveIcon: toBoolean(showRemove),
        showDownloadIcon: false,
      };
    }
    return this.showList;
  };

  /** 判断是否显示预览图 **/
  handlePreview = (file: UploadFile) => {
    // if (file.type.indexOf('image') > -1) {
    //   if (file.url) {
    //     this.previewImage = file.url;
    //   } else {
    //     this.previewImage = file.thumbUrl;
    //   }
    //   this.previewVisible = true;
    // }
    this.showImg(file);
  };

  registerOnChange(fn: (_: any) => void): void {
    this.onChange = fn;
  }

  registerOnTouched(fn: () => void): void {
    this.onTouched = fn;
  }

  showImg(file) {
    let list = [];
    list.push(file);

    this._fileList.forEach((_file) => {
      if (_file.id != file.id) {
        list.push(_file);
      }
    });

    let option = {
      title: '预览图片',
      _fileList: list,
    };

    this.openUploadDialog(option, (result: any) => {
    });
  }

  openUploadDialog(option: any, callback: any, dialog?: any) {

    let body: any = { ...option };

    const openDialog = dialog ? dialog : ApesPreviewDialogComponent;
    const dialogRef = this.modalService.create({
      apesWidth: '45vw',
      apesTitle: body.title,
      apesContent: openDialog,
      apesComponentParams: body,
      apesFooter: [
        {
          label: '取消',
          type: 'default',
          onClick: (componentInstance) => {
            dialogRef.destroy(componentInstance['fileList']);
          },
        },
        {
          label: '确定',
          type: 'primary',
          onClick: (componentInstance) => {
            dialogRef.destroy(componentInstance['fileList']);
          },
        },
      ],
    });

    return dialogRef.afterClose.subscribe((result) => callback(result));
  }
}
